package cn.lsoft.undoner.service.impl;

import cn.lsoft.undoner.dao.MessageDao;
import cn.lsoft.undoner.model.MessageRequest;
import cn.lsoft.undoner.model.RabbitQueue;
import cn.lsoft.undoner.service.MailSendService;
import cn.lsoft.undoner.service.RabbitMQService;
import cn.lsoft.undoner.service.ScheduleService;
import cn.lsoft.undoner.util.DataTimeUtils;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.apache.log4j.Logger;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.*;

/**
 * @author <A HREF="mailto:undoner@gmail.com">undoner</A>
 * @date 11-25-2014
 */
@Service
public class ScheduleServiceImpl implements ScheduleService {
    private static final Logger LOGGER = Logger.getLogger(ScheduleServiceImpl.class);
    public static final String TIMEZONE_ID = "UTC";

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Value("${mq.message.queue}")
    private String messageQueue;

    @Value("${mq.message.dead.queue}")
    private String messageDeadQueue;

    @Value("${mq.message.queue.alert.size:0}")
    private int messageQueueAlertSize;

    @Value("${mq.message.dead.queue.alert.size:0}")
    private int messageDeadQueueAlertSize;

    @Qualifier("messageDaoImpl")
    @Autowired
    private MessageDao messageDao;

    @Qualifier("rabbitMQServiceImpl")
    @Autowired
    private RabbitMQService rabbitMQService;

    @Qualifier("mailSendServiceImpl")
    @Autowired
    private MailSendService mailSendService;

    private Gson gson;

    private static Hashtable<String,Long> hsMqLimit = new Hashtable<String,Long>();

    @PostConstruct
    public void init() {
        gson = new GsonBuilder().create();
    }

    /**
     * 定时向mq消息队列提交消息
     * @param
     * @return
     * @throws Exception
     */
    @Scheduled(cron = "${message.create.queue.cron:0 1 * * * ?}")
    @Override
    public void createQueue()  throws Exception{
        MessageRequest messageRequest =new MessageRequest();
        messageRequest.setRequestUuid(UUID.randomUUID().toString());
        messageRequest.setContent("Content：" + String.valueOf(System.currentTimeMillis()));
        messageRequest.setStatus(1);
        messageRequest.setRequestTime(DataTimeUtils.getCurrentTime());
        sendQueue(messageRequest);
    }

    /**
     * 定时查询数据库中消息
     * @param
     * @return
     * @throws Exception
     */
    @Scheduled(cron = "${message.query.queue.cron:0 1 * * * ?}")
    @Override
    public void queryQueue()  throws Exception{
        List<MessageRequest> messageList = messageDao.queryMessageList();
        LOGGER.debug("queryQueue:" + gson.toJson(messageList));
    }

    /**
     * 定时查询超过预设数量的队列，发邮件报警
     * @param
     * @return
     * @throws Exception
     */
    @Scheduled(cron = "${mq.size.alert.cron:0 1 * * * ?}")
    @Override
    public void listExceptionQueue()  throws Exception{
        List<RabbitQueue> allList = rabbitMQService.listMessageReadyAllQueue();
        LOGGER.debug("listExceptionQueue:" +allList.size());
        for(RabbitQueue rabbitQueue:allList){
            if(rabbitQueue.getName().equals(messageQueue)){
                if(rabbitQueue.getMessages_ready()>messageQueueAlertSize){
                    LOGGER.debug(rabbitQueue.getName() + ":" + rabbitQueue.getMessages_ready());
                    sendMailMqAlertMsg(rabbitQueue.getName(), rabbitQueue.getMessages_ready());
                }
            }else if(rabbitQueue.getName().equals(messageDeadQueue)){
                if(rabbitQueue.getMessages_ready()>messageDeadQueueAlertSize){
                    LOGGER.debug(rabbitQueue.getName() + ":" + rabbitQueue.getMessages_ready());
                    sendMailMqAlertMsg(rabbitQueue.getName(), rabbitQueue.getMessages_ready());
                }
            }
        }
    }

    /**
     * queue的数量发送变化时，发邮件报警
     * @param
     * @return
     * @throws Exception
     */
    public void sendMailMqAlertMsg(String queueName , Long queueSize) throws Exception{
        if(queueName.equals(messageQueue)||queueName.equals(messageDeadQueue)){
            if(hsMqLimit.contains(queueName)){
                if(hsMqLimit.get(queueName)==queueSize){
                    return;
                }else{
                    hsMqLimit.put(queueName,queueSize);
                }
            }else{
                hsMqLimit.put(queueName,queueSize);
            }
        }

        mailSendService.sendMailMqAlertMsg(queueName, queueSize);
    }

    /**
     * 发送mq消息
     * @param
     * @return
     * @throws Exception
     */
    private void sendQueue(MessageRequest messageRequest)  throws Exception{
        rabbitTemplate.convertAndSend(messageQueue, gson.toJson(messageRequest));
        LOGGER.debug("send Queue_Success,uuid:" + messageRequest.getRequestUuid());
    }

}
